import pygame
from sys import exit
from bullet import *
from hero import *
from enemybullet import *
from setting import *
from enemyplane import *
from boss import *
from herobullet import *
from missle import *
from background import *
from blast import *
from supply import *


#定义屏幕类
class MainScene(object):
    #初始化
    def __init__(self):
        pygame.mixer.pre_init()
        pygame.init()
        pygame.mixer.init()
        pygame.font.init()
        pygame.mouse.set_visible(False)

        self.size = (SCENEWIDTH, SCENEHEIGHT)
        self.scene = pygame.display.set_mode((SCENEWIDTH, SCENEHEIGHT), 1, 32)
        pygame.display.set_caption("自学飞机大战--精灵版")
        self.background = Background(self.scene)

        self.hero = Hero(self.scene)
        self.hero.set_pos(SCENEWIDTH // 2 - 50, SCENEHEIGHT - 200)
        self.hero_sprite = pygame.sprite.RenderUpdates()
        self.hero_sprite.add(self.hero)

        enemy = EnemyPlane(self.scene)
        enemy.set_plane_type(1)
        enemy.set_pos(random.randint(0, SCENEWIDTH - 200), 0)
        enemy2 = EnemyPlane(self.scene)
        enemy2.set_plane_type(6)
        enemy.set_pos(random.randint(0, SCENEWIDTH - 200), 0)
        self.enemy_sprite = pygame.sprite.RenderUpdates()
        self.enemy_sprite.add(enemy)
        self.enemy_sprite.add(enemy2)

        self.boss_sprite = pygame.sprite.RenderUpdates()
        self.supply_sprite = pygame.sprite.RenderUpdates()

        self.blast_sprite = pygame.sprite.RenderUpdates()

        self.hero_bullet_sprite = pygame.sprite.RenderUpdates()
        self.enemy_bullet_sprite = pygame.sprite.RenderUpdates()
        self.boss_bullet_sprite = pygame.sprite.RenderUpdates()
        self.hero_missle_sprite = pygame.sprite.RenderUpdates()

        pygame.time.set_timer(CREATE_ENEMY_TIME, 1000)
        pygame.time.set_timer(CREATE_SUPPLY_TIME, 1000)
        self.clock = pygame.time.Clock()

        self.my_font = pygame.font.SysFont('kaiti', 16, True, True)
        self.score_font = pygame.font.SysFont('kaiti', 30, True, True)

        # 创建记录
        self.hero_score = 0
        # 游戏等级
        self.gamelevel = 1

    #绘制各个元素
    def draw(self):
        self.background.draw()
        self.hero_sprite.draw(self.scene)
        self.hero_bullet_sprite.draw(self.scene)
        self.enemy_sprite.draw(self.scene)
        self.enemy_bullet_sprite.draw(self.scene)
        self.boss_sprite.draw(self.scene)
        self.boss_bullet_sprite.draw(self.scene)

        self.hero_missle_sprite.draw(self.scene)
        self.blast_sprite.draw(self.scene)
        self.supply_sprite.draw(self.scene)

        # 绘制玩家信息
        hero_info = self.my_font.render('score:' + str(self.hero_score), True,
                                        (255, 0, 0))
        hero_life = self.my_font.render("生命:" + str(self.hero.HP), True,
                                        (0, 255, 0))

        self.scene.blit(hero_info, (0, 0))
        self.scene.blit(hero_life, (self.size[0] - 100, 0))
        #sprite里的draw()函数是不能自动调用的，精灵组里的draw()函数，只是用来显示本体精灵，而不能显示该精灵用
        #draw()或者其他方式创建的图片，所以手动调用精灵自己的绘制函数。
        #不过，可以用sprite的 layer来进行高级编写，目前尚未测试。
        if self.boss_sprite:
            for boss in self.boss_sprite:
                #显示BOSS的生命条。
                boss.draw_life_indicate()


    def update(self):
        self.background.update()
        self.hero_sprite.update()
        self.enemy_sprite.update()
        self.boss_sprite.update()
        self.boss_bullet_sprite.update()

        self.hero_bullet_sprite.update()
        self.enemy_bullet_sprite.update()
        #跟踪弹,要对中心进行计算,下一步
        # boss_pos = self.boss.get_pos()
        #先打BOSS
        if len(self.boss_sprite):

            boss_pos = vect(self.boss.rect.centerx, self.boss.rect.centery)
            for bul in self.hero_missle_sprite.sprites():
                bul.set_target_coordinate(boss_pos)
        #BOSS不在了，打敌人飞机
        elif len(self.enemy_sprite):
            # target_enemys = self.enemy_sprite
            for enemy in self.enemy_sprite:
                enemy_pos = vect(enemy.rect.centerx, enemy.rect.centery)
                for bul in self.hero_missle_sprite.sprites():
                    bul.set_target_coordinate(enemy_pos)
                break
        #都不在了，打屏幕中心，知道跑出屏幕，自己销毁
        else:
            for bul in self.hero_missle_sprite.sprites():
                bul.set_target_coordinate(vect(SCENEWIDTH // 2, -400))

        self.hero_missle_sprite.update()

        self.blast_sprite.update()
        self.supply_sprite.update()

    def collideEvent(self):

        # 英雄导弹打飞机
        hero_missle_enemy = pygame.sprite.groupcollide(
            self.hero_missle_sprite, self.enemy_sprite, True, True)
        if hero_missle_enemy:
            for enemy in hero_missle_enemy:
                rect = enemy.rect
                blast = Blast(self.scene)
                blast.set_pos(rect.centerx - blast.rect.width // 2,
                              rect.centery - blast.rect.height // 2)
                self.blast_sprite.add(blast)
                mus = pygame.mixer.Sound('./musics/boom_music.ogg')
                mus.set_volume(6)
                mus.play()
        #英雄导弹打BOSS
        hero_missle_boss = pygame.sprite.groupcollide(
            self.hero_missle_sprite, self.boss_sprite, True, False,
            pygame.sprite.collide_mask)
        if hero_missle_boss:
            for missle in hero_missle_boss:
                rect = missle.rect
                blast = Blast(self.scene)
                blast.set_pos(rect.centerx - blast.rect.width // 2,
                              rect.centery - blast.rect.height // 2)
                self.blast_sprite.add(blast)
                #boss的生命扣除2
                self.boss.HP -= missle.damage
                # print (hero_missle_boss[missle])
                mus = pygame.mixer.Sound('./musics/boom.wav')
                mus.set_volume(6)
                mus.play()

        #英雄子弹打飞机
        hero_shot_enemy = pygame.sprite.groupcollide(
            self.hero_bullet_sprite, self.enemy_sprite, True, False)
        if hero_shot_enemy:
            for hero_bullet in hero_shot_enemy:  # in hero_shot_enemy.keys():
                rect = hero_bullet.rect
                blast = Blast(self.scene)
                blast.set_pos(rect.centerx - blast.rect.width // 2,
                              rect.centery - blast.rect.height // 2)
                self.blast_sprite.add(blast)
                self.hero_score += 1
                #当前子弹打中的敌人
                # print(hero_shot_enemy[hero_bullet])
                enemys = hero_shot_enemy[hero_bullet]
                for enemy in enemys:
                    enemy.HP -= hero_bullet.damage
                    # print(enemy.HP)
                
        #英雄子弹打BOSS
        hero_shot_boss = pygame.sprite.groupcollide(
            self.hero_bullet_sprite, self.boss_sprite, True, False,
            pygame.sprite.collide_mask)
        if hero_shot_boss:
            for bullet in hero_shot_boss:
                rect = bullet.rect
                blast = Blast(self.scene)
                blast.set_pos(rect.centerx - blast.rect.width // 2,
                              rect.centery - blast.rect.height // 2)
                self.blast_sprite.add(blast)
                self.boss.HP -= bullet.damage
        #英雄撞飞机
        hero_crash_enemys = pygame.sprite.spritecollide(
            self.hero, self.enemy_sprite, True)
        #英雄撞BOSS
        boss_crash_hero = pygame.sprite.spritecollide(self.hero,
                                                      self.boss_sprite, False)

        #飞机打英雄
        enemy_shot_hero = pygame.sprite.spritecollide(
            self.hero, self.enemy_bullet_sprite, True,
            pygame.sprite.collide_mask)
        if enemy_shot_hero:
            for her in enemy_shot_hero:
                rect = her.rect
                blast = Blast(self.scene)
                blast.set_pos(rect.centerx - blast.rect.width // 2,
                              rect.centery - blast.rect.height // 2)
                self.blast_sprite.add(blast)
                self.hero.HP -= 1

        #BOSS打英雄
        buss_shot_hero = pygame.sprite.spritecollide(
            self.hero, self.boss_bullet_sprite, True,
            pygame.sprite.collide_mask)
        if buss_shot_hero:
            for her in buss_shot_hero:
                rect = her.rect
                blast = Blast(self.scene)
                blast.set_pos(rect.centerx - blast.rect.width // 2,
                              rect.centery - blast.rect.height // 2)
                self.blast_sprite.add(blast)
                self.hero.HP -= 1

        supply_hero = pygame.sprite.spritecollide(self.hero,
                                                  self.supply_sprite, True)
        if supply_hero:
            for v in supply_hero:
                #子弹等级到四封顶，后面的太卡了。
                if self.hero.bullet_level == 5:
                    return
                self.hero.bullet_level += 1

    #处理键盘和鼠标相应
    def handleEvent(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                exit()

            # 判断事件类型是否是键盘按下事件
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_j:
                    #普通射击
                    self.hero.set_bullet_motion_type(self.hero.bullet_level)
                    self.hero.fire_key_down(pygame.K_j)
                elif event.key == pygame.K_k:
                    # self.hero.set_motion_type(1)
                    self.hero.missle_fire()
                # elif event.key == pygame.K_l:
                #     self.hero.set_bullet_motion_type(1)
                #     self.hero.fire()
                # elif event.key == pygame.K_h:
                #     self.hero.set_bullet_motion_type(2)
                #     self.hero.fire()
                #跟踪弹
                # elif event.key == pygame.K_m:

                # self.missle.rotate(angle)
                elif event.key == pygame.K_a:
                    self.hero.key_down(pygame.K_a)
                elif event.key == pygame.K_d:
                    self.hero.key_down(pygame.K_d)
                elif event.key == pygame.K_w:
                    self.hero.key_down(pygame.K_w)
                elif event.key == pygame.K_s:
                    self.hero.key_down(pygame.K_s)
                #ESC 退出
                elif event.key == pygame.K_ESCAPE or event.key == pygame.K_F4:
                    pygame.quit()
                    exit()
            #按键松开
            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_a:
                    self.hero.key_up(pygame.K_a)
                elif event.key == pygame.K_d:
                    self.hero.key_up(pygame.K_d)
                elif event.key == pygame.K_w:
                    self.hero.key_up(pygame.K_w)
                elif event.key == pygame.K_s:
                    self.hero.key_up(pygame.K_s)
                elif event.key == pygame.K_j:
                    self.hero.fire_key_up(pygame.K_j)
            #自定义按键，添加飞机
            elif event.type == CREATE_ENEMY_TIME:
                self.CreateEnemy()
            elif event.type == CREATE_SUPPLY_TIME:
                self.CreateSupply()

        self.hero.press_fire()
        self.hero.press_move()
        self.hero_bullet_sprite.add(self.hero.bullet_sprite)
        self.hero_missle_sprite.add(self.hero.missle_sprite)
        for enemy in self.enemy_sprite:
            # enemy.set_fire_type(0)SSSSS
            enemy.fire()
            self.enemy_bullet_sprite.add(enemy.bullet_sprite)
        for boss in self.boss_sprite:
            # boss.set_fire_type(1)
            boss.fire()
            self.boss_bullet_sprite.add(boss.bullet_sprite)

    def CreateEnemy(self):
        if self.gamelevel == 1 and self.hero_score < GAMELEVEL1:
            b = random.randint(2, 4)
            for v in range(0, b):
                enemy = EnemyPlane(self.scene)
                enemy.set_plane_type(random.randint(1, 3))
                enemy.set_bullet_type(random.randint(0, 2))
                enemy.set_bullet_motion_type(random.randint(0, 3))
                enemy.set_pos(random.randint(-100, SCENEWIDTH - 200), -50)
                enemy.set_pos(random.randint(-100, SCENEWIDTH - 200), -50)
                self.enemy_sprite.add(enemy)

        elif self.gamelevel == 1 and self.hero_score >= GAMELEVEL1:
            b = random.randint(2, 4)
            for v in range(0, b):
                enemy = EnemyPlane(self.scene)
                enemy.set_plane_type(random.randint(1, 3))
                enemy.set_bullet_type(random.randint(0, 2))
                enemy.set_bullet_motion_type(random.randint(0, 3))
                enemy.set_pos(random.randint(-100, SCENEWIDTH - 200), -50)
                enemy.set_pos(random.randint(-100, SCENEWIDTH - 200), -50)
                self.enemy_sprite.add(enemy)
            if self.hero_score > GAMELEVEL2:
                self.gamelevel = 2
        elif self.gamelevel == 2 and self.hero_score >= GAMELEVEL2:
            b = random.randint(2, 5)
            for v in range(0, b):
                enemy = EnemyPlane(self.scene)
                enemy.set_plane_type(random.randint(3, 5))
                enemy.set_bullet_type(random.randint(0, 3))
                enemy.set_bullet_motion_type(random.randint(0, 3))
                enemy.set_pos(random.randint(-100, SCENEWIDTH - 200), -50)
                enemy.set_pos(random.randint(-100, SCENEWIDTH - 200), -50)
                self.enemy_sprite.add(enemy)
            if self.hero_score > GAMELEVEL3:
                self.gamelevel = 3
        elif self.gamelevel == 3 and self.hero_score >= GAMELEVEL3:
            b = random.randint(2, 6)
            for v in range(0, b):
                enemy = EnemyPlane(self.scene)
                enemy.set_plane_type(random.randint(4, 8))
                enemy.set_bullet_type(random.randint(0, 4))
                enemy.set_bullet_motion_type(random.randint(0, 3))
                enemy.set_pos(random.randint(-100, SCENEWIDTH - 200), -50)
                enemy.set_pos(random.randint(-100, SCENEWIDTH - 200), -50)
                self.enemy_sprite.add(enemy)
            if self.hero_score > GAMELEVEL4:
                self.gamelevel = 4
        elif self.gamelevel == 4 and self.hero_score >= GAMELEVEL4:
            self.boss = BossPlane(self.scene)
            self.boss.set_motion_tpye(0)
            self.boss_sprite.add(self.boss)
            self.gamelevel = 5
        else:
            pass

    def CreateSupply(self):
        """ 
        create supply
        """
        supply = Supply(self.scene)
        supply.set_pos(200, 0)
        self.supply_sprite.add(supply)

    #运行主程序
    def runScene(self):
        # 播放背景音乐
        pygame.mixer.music.load('musics/bgm.mp3')
        pygame.mixer.music.play(-1)

        while True:
            #设置最大帧数 100
            self.clock.tick(100)
            self.update()
            self.draw()
            self.collideEvent()
            self.handleEvent()

            pygame.display.update()
            # pygame.time.delay(100)


if __name__ == '__main__':
    mainScene = MainScene()
    mainScene.runScene()